home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / SECURITY / MNGLR140 / ASMLEX.L next >
Text File  |  1996-05-01  |  8KB  |  245 lines

  1. %{
  2. {*  Assembler parsing for Mangler, see MANGLER.L
  3.     Copyright (C) 1993  Berend de Boer
  4.  
  5.     This program is free software for noncommercial users; you can
  6.     redistribute it and/or modify it under the terms of the license,
  7.     stated in de accompanying file LICENSE.TXT.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     license for more details.
  13.  
  14.     See the accompanying READ.ME file for information on contacting the
  15.     author.
  16.  
  17.  
  18. $Author: Berend_de_Boer $
  19. $Date: 93/04/29 07:52:25 $
  20. $Revision: 1.2 $
  21.  
  22. Last changes:
  23. 93-04-19  Fixed the & identifier override bug
  24. *}
  25.  
  26. procedure ParseAsm;
  27.  
  28. %}
  29.  
  30. NQUOTE    [^']
  31. DQUOTE    [^'}]
  32.  
  33. %%
  34.  
  35. %{
  36.   function is_keyword(const id : string) : Boolean;
  37.   {**}
  38.   const
  39.     id_len = 6;
  40.   type
  41.     Ident = string[id_len];
  42.   const
  43.     (* table of assembler keywords: *)
  44.     no_of_keywords = 192;
  45.     keyword : array [1..no_of_keywords] of Ident = (
  46.       'AAA', 'AAD', 'AAM', 'AAS', 'ADC', 'ADD', 'AH', 'AL', 'AND', 'AND',
  47.       'AX', 'BH', 'BL', 'BOUND', 'BP', 'BX', 'BYTE', 'CALL', 'CBW', 'CH',
  48.       'CL', 'CLC', 'CLD', 'CLI', 'CMC', 'CMP', 'CMPS', 'CMPSB', 'CMPSD',
  49.       'CMPSW', 'CS', 'CX', 'DAA', 'DAS', 'DEC', 'DH', 'DI', 'DIV', 'DL', 'DS',
  50.       'DWORD', 'DX', 'ENTER', 'ES', 'FAR', 'HIGH', 'HLT', 'IDIV', 'IMUL',
  51.       'IN', 'INC', 'INS', 'INSB', 'INSD', 'INSW', 'INT', 'INTO', 'IRET', 'JA',
  52.       'JAE', 'JB', 'JBE', 'JC', 'JCXZ', 'JE', 'JG', 'JGE', 'JL', 'JLE', 'JMP',
  53.       'JNA', 'JNAE', 'JNB', 'JNBE', 'JNC', 'JNE', 'JNG', 'JNGE', 'JNL',
  54.       'JNLE', 'JNO', 'JNP', 'JNS', 'JNZ', 'JO', 'JP', 'JPE', 'JPO', 'JS',
  55.       'JZ', 'JZ', 'LAHF', 'LAR', 'LDS', 'LEA', 'LEAVE', 'LES', 'LGDT', 'LIDT',
  56.       'LLDT', 'LMSW', 'LOCK', 'LODS', 'LODSB', 'LODSW', 'LOOP', 'LOOPE',
  57.       'LOOPNE', 'LOOPNZ', 'LOOPZ', 'LOW', 'LSL', 'LTR', 'MOD', 'MOV', 'MOVS',
  58.       'MOVSB', 'MOVSW', 'MUL', 'NEAR', 'NEG', 'NOP', 'NOT', 'NOT', 'OFFSET',
  59.       'OR', 'OR', 'OUT', 'OUTS', 'OUTSB', 'OUTSW', 'POP', 'POPA', 'POPF',
  60.       'PTR', 'PUSH', 'PUSHA', 'PUSHF', 'QWORD', 'RCL', 'RCR', 'REP', 'REPE',
  61.       'REPNE', 'REPNZ', 'REPZ', 'RET', 'ROL', 'ROR', 'SAHF', 'SAL', 'SAR',
  62.       'SBB', 'SCAS', 'SCASB', 'SCASW', 'SEG', 'SEGDS', 'SEGES', 'SEGSS', 'SGDT', 'SHL', 'SHL', 'SHR',
  63.       'SHR', 'SI', 'SIDT', 'SLDT', 'SMSW', 'SP', 'SS', 'ST', 'STC', 'STD',
  64.       'STI', 'STOS', 'STOSB', 'STOSW', 'STR', 'SUB', 'TBYTE', 'TEST', 'TYPE',
  65.       'VERR', 'VERW', 'WAIT', 'WORD', 'XCHG', 'XLAT', 'XLATB', 'XOR', 'XOR');
  66.   var m, n, k : integer;
  67.   begin
  68.     m := 1; n := no_of_keywords;
  69.     while m<=n do  begin
  70.       k := m+(n-m) div 2;
  71.       if id=keyword[k]
  72.        then  begin
  73.          is_keyword := true;
  74.          Exit;
  75.        end
  76.        else  if id>keyword[k]
  77.               then  m := k+1
  78.               else  n := k-1
  79.     end;  { of while }
  80.     is_keyword := false
  81.   end;
  82.  
  83. var
  84.   Stop : Boolean;
  85. %}
  86.  
  87.  
  88.  
  89.  
  90. [A-Za-z]([a-zA-Z])*       begin
  91.                             yytext := UpStr(yytext);
  92.                             if is_keyword(yytext)
  93.                              then  return(KEYWORD)
  94.                              else  begin
  95.                                if yytext = 'END'
  96.                                 then  return(_END)
  97.                                 else  return(IDENTIFIER);
  98.                              end;
  99.                           end;
  100.  
  101. [a-zA-Z_]([a-zA-Z0-9_])*  begin
  102.                             yytext := UpStr(yytext);
  103.                             return(IDENTIFIER);
  104.                           end;
  105.  
  106. "&"                       return(AMPERSAND);
  107.  
  108. [@]+([a-zA-Z0-9_])+       return(_LABEL);
  109.  
  110. ";"              return(SEMICOLON);
  111. "."              return(DOT);
  112.  
  113. '({NQUOTE}|'')*'          return(CHARACTER_STRING);
  114.  
  115. [0-9]([0-9-a-fA-F])*[hH]  |
  116. [$]([0-9a-fA-F])+         |
  117. [0-9]+                    return(NUMBER);
  118.  
  119. "{$"({DQUOTE})*"}"        return(DIRECTIVE);
  120.  
  121. "(*"                      begin
  122.                             Stop := FALSE;
  123.                             repeat
  124.                               if (get_char = '*') and (get_char = ')') then
  125.                                 Stop := TRUE;
  126.                             until Stop;
  127.                           end;
  128.  
  129. "{"                       begin
  130.                 repeat
  131.                             until get_char = '}';
  132.                           end;
  133.  
  134. [ \t\f]              ;
  135.  
  136. \n                        begin
  137.                             if Random(50) = 25 then
  138.                               WriteProgress;
  139.                             return(NEWLINE);
  140.                           end;
  141.  
  142. .                         return(OTHER);
  143.  
  144. %%
  145. (**)
  146.  
  147.   function GiveEncodingFor(s : string) : string;
  148.   {* DO NOT MAKE s a const string!!! *}
  149.   {* should be equal to function in MANGLER.PAS *}
  150.   { PRE -
  151.     POST - contents of yytext is destroyed
  152.   }
  153.   var
  154.     p,d : PScopeCol;
  155.     e : string;
  156.     Index : integer;
  157.   begin
  158.     if yylex = DOT
  159.      then  begin
  160.      {* a dot was used to select a different scope *}
  161.        p := GetScope(s, Index);
  162.        if p = nil
  163.         then  begin     {* an unknown scope was selected *}
  164.           e := s + '.';
  165.           while (yylex = IDENTIFIER) do  begin
  166.             e := e + yytext;
  167.             if yylex = DOT
  168.              then  e := e + '.'
  169.              else  Break;
  170.           end;
  171.           yyless(0);
  172.         end
  173.         else  begin
  174.           PushScope(CurrentScope);
  175.           CurrentScope := p^.AtScope(Index);
  176.           e := p^.AtHashedName(Index) + '.';
  177.           while (yylex = IDENTIFIER) do  begin
  178.             if CurrentScope = nil
  179.              then  begin
  180.                e := e + yytext;
  181. (* why this source??? if nil you don't know anything it seems
  182.                d := GetScope(yytext, Index);
  183.                if d <> nil
  184.                 then  e := e + GiveEncodingFor(yytext)
  185.                 else  e := e + yytext;
  186. *)
  187.              end
  188.              else  begin
  189.                if CurrentScope^.Search(@yytext, Index)
  190.                 then  e := e + CurrentScope^.AtHashedName(Index)
  191.                 else  e := e + yytext;
  192.              end;
  193.             if yylex = DOT
  194.              then  begin
  195.                if CurrentScope <> nil then
  196.                  if CurrentScope^.Count = 0
  197.                   then  CurrentScope := nil
  198.                   else  CurrentScope := CurrentScope^.AtScope(Index);
  199.                e := e + '.';
  200.              end
  201.              else  break;
  202.           end;  { of while }
  203.           yyless(0);
  204.           CurrentScope := PopScope;
  205.         end;
  206.        GiveEncodingFor := e;
  207.      end
  208.      else  begin
  209.        yyless(0);
  210.        p := GetScope(s, Index);
  211.        if p = nil
  212.         then  GiveEncodingFor := s
  213.         else  GiveEncodingFor := p^.AtHashedName(Index)
  214.      end;
  215.   end;
  216.  
  217.  
  218. begin
  219.   write(yyoutput, yytext, ' ');
  220.   while yylex <> _END do  begin
  221.     case yyretval of
  222.       IDENTIFIER : begin
  223.           write(yyoutput, GiveEncodingFor(yytext));
  224.         end;
  225.       NEWLINE : writeln(yyoutput, '{}');
  226.       AMPERSAND : begin
  227.           write(yyoutput, yytext);
  228.           yylex;
  229.           write(yyoutput, GiveEncodingFor(yytext));
  230.         end;
  231.     else  write(yyoutput, yytext, ' ');
  232.     end; { of case }
  233.   end; { of while }
  234.   writeln(yyoutput);
  235.   write(yyoutput, yytext);
  236.   if AssemblerSection then  begin
  237.     Section := PopSection;
  238.     CurrentScope := PopScope;
  239.     if ObjectImpl then  begin
  240.       CurrentScope := PopScope;
  241.       ObjectImpl := FALSE;
  242.     end;
  243.     AssemblerSection := FALSE;
  244.   end;
  245. end;